package com.jwsoft.manager.core.task.address;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bifang.engine.assistant.core.enums.AuthStatusEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.jwsoft.manager.common.enums.MatchingStatusEnum;
import com.jwsoft.manager.common.vo.eduAddressTree.AddressTreeVO;
import com.jwsoft.manager.common.vo.eduAddressTree.AddressVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.core.dao.model.*;
import com.jwsoft.manager.core.dao.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 学校匹配-地址格式化后触发
 *
 * @author fangs
 */
@Slf4j
@Service
public class SchoolMatchObserver implements AddressObserver {
    /**
     * 地址链最小长度
     */
    private static final int ADDRESS_CHAIN_MIN_SIZE = 2;

    /**
     * 需要匹配学校的学段
     */
    private static final List<String> MATCH_SCHOOL_CATEGORY = Arrays.asList("2", "3");
    @Autowired
    EduAddressService eduAddressService;
    @Autowired
    EduAddressSchoolService eduAddressSchoolService;
    @Autowired
    EduSchoolService eduSchoolService;
    @Autowired
    EduAddressTreeSchoolService eduAddressTreeSchoolService;
    @Autowired
    EduAddressCategoryService eduAddressCategoryService;
    @Autowired
    EduAddressSchoolAuditService eduAddressSchoolAuditService;
    @Autowired
    CommonIntegration commonIntegration;

    @Override
    public void invoke(AddressVO addressVO) {
        String eduAddressId = addressVO.getEduAddressId();
        EduAddress eduAddress = eduAddressService.getById(eduAddressId);
        if (MatchingStatusEnum.SUCCESS.getType().equals(eduAddress.getMatchingStatus())) {
            //地址已匹配学校成功，将学校信息保存到地址树中
            QueryWrapper<EduAddressSchool> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().select(EduAddressSchool::getSchoolId, EduAddressSchool::getAddressId)
                    .eq(EduAddressSchool::getAddressId, eduAddressId)
                    .eq(EduAddressSchool::getAuthStatus, AuthStatusEnum.YES.getType());
            List<EduAddressSchool> eduAddressSchools = eduAddressSchoolService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(eduAddressSchools)) {
                for (EduAddressSchool eduAddressSchool : eduAddressSchools) {
                    this.saveTreeAndSchool(addressVO.getAddressChain(), eduAddressSchool.getSchoolId());
                }
            }
        } else {
            //根据地址树的学校信息，匹配学校
            this.matchSchool(addressVO);
        }
    }

    /**
     * 根据地址匹配学校信息
     *
     * @param addressVO 地址信息
     * @author fangs
     */
    private void matchSchool(AddressVO addressVO) {
        List<AddressTreeVO> addressChain = addressVO.getAddressChain();
        if (addressChain.size() < ADDRESS_CHAIN_MIN_SIZE) {
            throw new AppException(String.format("地址匹配学校失败：地址链小于%d", ADDRESS_CHAIN_MIN_SIZE));
        }
        //需要匹配的学段
        for (String schoolCategory : MATCH_SCHOOL_CATEGORY) {
            QueryWrapper<EduAddressCategory> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().select(EduAddressCategory::getId, EduAddressCategory::getSchoolNum)
                    .eq(EduAddressCategory::getAddressId, addressVO.getEduAddressId())
                    .eq(EduAddressCategory::getSchoolCategory, schoolCategory);
            EduAddressCategory eduAddressCategory = eduAddressCategoryService.getOne(queryWrapper);
            if (eduAddressCategory == null) {
                //初始化 学段-地址关联表 信息
                eduAddressCategory = new EduAddressCategory();
                eduAddressCategory.setSchoolCategory(schoolCategory);
                eduAddressCategory.setAddressName(addressVO.getOriginAdd());
                eduAddressCategory.setAddressId(addressVO.getEduAddressId());
                eduAddressCategory.setMatchingStatus(MatchingStatusEnum.NODO.getType());
                eduAddressCategory.setTreeId(addressChain.get(addressChain.size() - 1).getAddressId());
                eduAddressCategory.setSchoolNum(0);
                eduAddressCategoryService.save(eduAddressCategory);
            } else {
                //如果该学段已经存在关联的学校则不匹配
                if (eduAddressCategory.getSchoolNum() != null && eduAddressCategory.getSchoolNum() > 0) {
                    continue;
                }
            }
            boolean matchFlag = false;
            boolean saveAuditFlag = true;
            String msg = null;
            //从叶子节点的上级节点依次往上遍历查找对应学段的学校
            List<EduAddressTreeSchool> addressTreeSchoolList = eduAddressTreeSchoolService.matchSchool2(schoolCategory, addressVO);
            if (!CollectionUtils.isEmpty(addressTreeSchoolList)) {
                matchFlag = true;
                //生成待审数据
                try {
                    saveAuditInfo(addressTreeSchoolList, addressVO);
                } catch (Exception e) {
                    saveAuditFlag = false;
                    if (e.getMessage().length() > 500) {
                        msg = e.getMessage().substring(0, 500);
                    }
                    log.error("保存学校-地址待审核信息失败"+e.getMessage());
                }
            }
            //修改地址和学段关联表匹配状态
            UpdateWrapper<EduAddressCategory> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(EduAddressCategory::getId, eduAddressCategory.getId());
            if (matchFlag) {
                updateWrapper.lambda().set(EduAddressCategory::getMatchingStatus, MatchingStatusEnum.PEND.getType())
                        .set(EduAddressCategory::getMatchingTime, new Date());
                if (saveAuditFlag) {
                    updateWrapper.lambda().set(EduAddressCategory::getMatchingMessage, MatchingStatusEnum.PEND.getName());
                } else {
                    updateWrapper.lambda().set(EduAddressCategory::getMatchingMessage, msg);
                }
            } else {
                updateWrapper.lambda().set(EduAddressCategory::getMatchingStatus, MatchingStatusEnum.FAIL.getType())
                        .set(EduAddressCategory::getMatchingTime, new Date())
                        .set(EduAddressCategory::getMatchingMessage, MatchingStatusEnum.FAIL.getName());
            }
            eduAddressCategoryService.update(updateWrapper);
        }
    }

    /**
     * 生成学校待审核信息
     *
     * @param list      匹配到的学校
     * @param addressVO 当前地址信息
     * @return 生成的待审核数据的数量
     * @author fangs
     */
    private Integer saveAuditInfo(List<EduAddressTreeSchool> list, AddressVO addressVO) {
        int saveNum = 0;
        List<AddressTreeVO> addressChain = addressVO.getAddressChain();
        Long leafId = addressChain.get(addressChain.size() - 1).getAddressId();
        for (EduAddressTreeSchool school : list) {
            QueryWrapper<EduAddressSchoolAudit> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(EduAddressSchoolAudit::getAddressId, addressVO.getEduAddressId())
                    .eq(EduAddressSchoolAudit::getSchoolId, school.getSchoolId());
            //如果该地址-学校已经存在审核数据则不生成
            if (eduAddressSchoolAuditService.count(queryWrapper) == 0) {
                //生成待审核数据
                EduAddressSchoolAudit schoolAudit = new EduAddressSchoolAudit();
                schoolAudit.setSchoolId(school.getSchoolId());
                schoolAudit.setAddressId(addressVO.getEduAddressId());
                schoolAudit.setAddressName(addressVO.getOriginAdd());
                schoolAudit.setSchoolName(school.getSchoolName());
                schoolAudit.setAreaCode(school.getAreaCode());
                schoolAudit.setTreeId(leafId);
                schoolAudit.setSchoolCategory(school.getSchoolCategory());
                schoolAudit.setAuthStatus(AuthStatusEnum.NODO.getType());
                eduAddressSchoolAuditService.save(schoolAudit);
                saveNum++;
            }
        }
        return saveNum;
    }

    /**
     * 保存地址树节点和学校的关联关系
     *
     * @param addressChain 地址链
     * @param schoolId     学校id
     * @author fangs
     */
    private void saveTreeAndSchool(List<AddressTreeVO> addressChain, String schoolId) {
        EduSchoolVO eduSchool = eduSchoolService.getDetail(schoolId);
        eduAddressTreeSchoolService.saveTreeAndSchool(addressChain, eduSchool);
    }

}
